﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Kokomo.Environment
{
	/// <summary>
	/// Represents a <see cref="DocumentTemplate"/> that is implemented as a delegate.
	/// </summary>
	/// <remarks>
	/// The environment uses this type to wrap imported extension delegates.
	/// To use this type, mark a method with <see cref="System.ComponentModel.Composition.ExportAttribute"/>, using
	/// <see cref="ContractName"/> as the contract name, as well as the metadata
	/// required by <see cref="IDocumentTemplateMetadata"/>.
	/// </remarks>
	public class DelegatedDocumentTemplate : DocumentTemplate
	{
		/// <summary>
		/// The name of the contract for extension methods.
		/// </summary>
		public const string ContractName = "DelegatedDocumentTemplate";

		/// <summary>
		/// Initializes a new instance of <see cref="DelegatedDocumentTemplate"/>.
		/// </summary>
		/// <param name="title">The title of the template.</param>
		/// <param name="instantiateDelegate">The delegate that instantiates documents.</param>
		/// <exception cref="ArgumentNullException"><paramref name="title"/> is <c>null</c>.</exception>
		/// <exception cref="ArgumentNullException"><paramref name="instantiateDelegate"/> is <c>null</c>.</exception>
		public DelegatedDocumentTemplate(
			UiString title,
			Func<DocumentViewModel> instantiateDelegate
			)
		{
			if (title == null) throw new ArgumentNullException("title");
			if (instantiateDelegate == null) throw new ArgumentNullException("instantiateDelegate");

			this._title = title;
			this._instantiateDelegate = instantiateDelegate;
		}

		private UiString _title;

		/// <summary>
		/// Gets the title of the template.
		/// </summary>
		public override UiString Title { get { return this._title; } }

		private Func<DocumentViewModel> _instantiateDelegate;

		/// <summary>
		/// Instantiates a document using this template.
		/// </summary>
		/// <returns>An instance of <see cref="DocumentViewModel"/>, if a document is created; otherwise, <c>null</c>.</returns>
		public override DocumentViewModel Instantiate()
		{
			return this._instantiateDelegate();
		}
	}
}
